package com.sunrise.generico.acesso;

import java.util.List;

import javax.annotation.Resource;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Example;
import org.hibernate.criterion.MatchMode;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.transaction.annotation.Transactional;

import com.sunrise.generico.entidade.iface.EntidadeManter;
import com.sunrise.generico.repositorio.iface.Repositorio;

public abstract class DaoService<E extends EntidadeManter> extends HibernateDaoSupport implements Repositorio<E>{
	

	@Transactional(readOnly = false)
	@Override
	public void alterar(E entity) {
		getHibernateTemplate().update(entity);
	}

	@Transactional(readOnly = false)
	@Override
	public void remover(E entity) {
		getHibernateTemplate().delete(entity);
	}

	@Transactional(readOnly = false)
	@Override
	public void inserir(E entity) {
		getHibernateTemplate().save(entity);
	}
	
	@Resource(name = "sessionFactory")
	protected void setSessionFactory2(SessionFactory sessionFactory) {
		setSessionFactory(sessionFactory);
	}

	@SuppressWarnings({ "unchecked", "hiding" })
	@Transactional(readOnly = true)
	public <E extends EntidadeManter> List<E> listar(Class<E> clazz) {
		Query query = createQuery("from " + clazz.getSimpleName());
		List<E> list = query.list();
		return list;
	}

	@SuppressWarnings({ "rawtypes" })
	public List executeQuery(String query, Object... args) {
		Query queryObj = createQuery(query, args);
		List list = queryObj.list();
		return list;
	}

	public Object executeQuerySingleResult(String query, Object... args) {
		Query obj = createQuery(query, args);
		obj.setMaxResults(1);
		return obj.uniqueResult();
	}

	@SuppressWarnings("hiding")
	private <E extends EntidadeManter> Query createQuery(String query, Object... args) {
		Query obj = getSession().createQuery(query);
		if (args != null) {
			int index = 0;
			for (Object arg : args) {
				obj.setParameter(index, arg);
				index++;
			}
		}
		return obj;
	}

	@SuppressWarnings({ "unchecked", "hiding" })
	@Transactional(readOnly = true)
	public <E extends EntidadeManter> List<E> searchByExample(Class<E> clazz,
			E example) {
		Criteria crit = getSession().createCriteria(clazz);
		Example sample = Example.create(example);
		sample.enableLike(MatchMode.START);
		sample.ignoreCase();
		sample.excludeZeroes();
		crit.add(sample);
		List<E> list = crit.list();
		return list;
	}

	@SuppressWarnings({ "unchecked", "hiding" })
	@Transactional(readOnly = true)
	public <E extends EntidadeManter> E getById(Long id, Class<E> clazz) {
		E entity = (E) getSession().get(clazz, id);
		return entity;
	}
	
}
